<?php

/**
 * @copyright (c) 2011 aircheng.com
 * @file request_class.php
 * @brief 处理 $_GET,$_POST 数据
 * @author chendeshan
 * @date 2010-12-2
 * @version 0.6
 * @see 4.6 更新了get参数的urldecode
 */

/**
 * @class IReq
 * @brief 获取$_GET,$_POST的数据
 */
class IReq
{
	/**
	 * @brief 获取键为$key的 $_GET 和 $_POST 传送方式的数据
	 * @param string $key $_GET 或 $_POST 的键
	 * @param string $type 传送方式 值: false:默认(先get后post); get:get方式; post:post方式;
	 * @return string $_GET 或者 $_POST 的值
	 * @note 优先获取 $_GET 方式的数据,如果不存在则获取 $_POST 方式的数据
	 */
	public static function get($key, $type = false)
	{
		//默认方式
		if ($type == false) {
			if (isset($_GET[$key])) {
				if (is_array($_GET[$key])) {
					array_walk_recursive($_GET[$key], function (&$v) {
						$v = urldecode($v);
					});
					return $_GET[$key];
				} else {
					return urldecode($_GET[$key]);
				}
			} else if (isset($_POST[$key])) {
				return $_POST[$key];
			} else {
				return null;
			}
		}

		//get方式
		else if ($type == 'get' && isset($_GET[$key])) {
			if (is_array($_GET[$key])) {
				array_walk_recursive($_GET[$key], function (&$v) {
					$v = urldecode($v);
				});
				return $_GET[$key];
			} else {
				return urldecode($_GET[$key]);
			}
		}

		//post方式
		else if ($type == 'post' && isset($_POST[$key])) {
			return $_POST[$key];
		}

		//无匹配
		else {
			return null;
		}
	}

	/**
	 * @brief 设置键为$key 的$_GET 或者 $_POST 的变量值
	 * @param string $key $_GET 或者 $_POST 键
	 * @param string $value 设置的值
	 * @param string $type 设置的类型 值: get:默认,get方式; post:post方式
	 */
	public static function set($key, $value, $type = 'get')
	{
		//get方式
		if ($type == 'get')
			$_GET[$key] = $value;

		//post方式
		else if ($type == 'post')
			$_POST[$key] = $value;
	}

	/**
	 * 获取请求参数的值，支持 GET、POST、JSON、form-data 和 urlencoded 请求
	 * @param string|null $key 参数键名，支持嵌套访问（如 'user.name'）
	 * @param mixed $default 默认值，如果参数不存在时返回
	 * @param string $filter 过滤器类型（如 FILTER_SANITIZE_STRING）
	 * @param string $method 请求方法（'get'、'post' 或 'request'）
	 * @return mixed 返回参数值或默认值
	 */
	public static function input($key = null, $default = null, $filter = '', $method = 'request')
	{
		// 获取请求体内容
		$contentType = isset($_SERVER['CONTENT_TYPE']) ? $_SERVER['CONTENT_TYPE'] : '';
		$data = [];

		if ($method === 'post' || $method === 'request') {
			if (stripos($contentType, 'application/json') !== false) {
				// JSON 请求
				$json = file_get_contents('php://input');
				$data = json_decode($json, true);

				// 检查数据是否成功解析
				if (json_last_error() !== JSON_ERROR_NONE) {
					// 返回默认值，并记录错误
					error_log("Failed to parse JSON data: " . json_last_error_msg());
					return $default;
				}
			} elseif (stripos($contentType, 'multipart/form-data') !== false || stripos($contentType, 'application/x-www-form-urlencoded') !== false) {
				// form-data 或 urlencoded 请求
				$data = $_POST;
			}
		}

		if ($method === 'get' || $method === 'request') {
			// 合并 GET 参数
			$data = array_merge($data, $_GET);
		}

		// 如果没有提供键，则直接返回整个数据
		if ($key === null) {
			return $data;
		}

		// 使用键值获取数据
		$keys = explode('.', $key); // 支持嵌套键，例如 'user.name'
		$value = $data;

		foreach ($keys as $k) {
			if (is_array($value) && isset($value[$k])) {
				$value = $value[$k];
			} else {
				return $default; // 如果键不存在，返回默认值
			}
		}

		// 应用过滤器（增强校验）
		if ($filter) {
			$allowed_filters = [
				'FILTER_SANITIZE_STRING',
				'FILTER_SANITIZE_NUMBER_INT',
				'FILTER_SANITIZE_EMAIL',
				'FILTER_SANITIZE_SPECIAL_CHARS'
			];
			$filter_constant = strtoupper($filter);
			if (!in_array($filter_constant, $allowed_filters)) {
				error_log("Invalid filter specified: $filter");
				$filter_constant = ''; // 降级为不过滤
			}
			if ($filter_constant) {
				$value = filter_var($value, constant($filter_constant));
			}
		}

		return $value;
	}

	// 判断请求方式（类型）
	public static function getMethod()
	{
		$method = isset($_SERVER['REQUEST_METHOD']) ? strtoupper($_SERVER['REQUEST_METHOD']) : 'GET';

		// 处理通过头信息覆盖方法的情况（常见于RESTful API）
		if (isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])) {
			$method = strtoupper($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']);
		}
		// 兼容某些框架的请求方法参数（如Yii的_method）
		if ($method === 'POST') {
			$overrideParam = isset($_POST['_method']) ? $_POST['_method'] : '';
			if (!empty($overrideParam)) {
				$method = strtoupper($overrideParam);
			}
			// 检查JSON请求体
			$contentType = isset($_SERVER['CONTENT_TYPE']) ? $_SERVER['CONTENT_TYPE'] : '';
			if (strpos($contentType, 'application/json') !== false) {
				$input = file_get_contents('php://input');
				$jsonData = json_decode($input, true);
				if (isset($jsonData['_method'])) {
					$method = strtoupper($jsonData['_method']);
				}
			}
		}
		return $method;
	}
}
